import React, { useRef, useState, useEffect } from 'react';

const UseRefDemo: React.FC = () => {
  // 1. 访问DOM元素
  const inputRef = useRef<HTMLInputElement>(null);
  const [inputValue, setInputValue] = useState('');

  // 2. 存储可变值（不会触发重新渲染）
  const renderCount = useRef(0);
  const [count, setCount] = useState(0);

  // 3. 存储定时器ID
  const intervalRef = useRef<NodeJS.Timeout | null>(null);
  const [isRunning, setIsRunning] = useState(false);
  const [timer, setTimer] = useState(0);

  // 4. 存储前一个值
  const prevCountRef = useRef<number>();

  // 5. 存储DOM元素集合
  const itemsRef = useRef<(HTMLDivElement | null)[]>([]);
  const [items, setItems] = useState<string[]>(['项目1', '项目2', '项目3']);

  // 6. 存储回调函数
  const callbackRef = useRef<() => void>();

  // 更新渲染次数（不会触发重新渲染）
  useEffect(() => {
    renderCount.current += 1;
  });

  // 存储前一个count值
  useEffect(() => {
    prevCountRef.current = count;
  });

  // 定时器逻辑
  useEffect(() => {
    if (isRunning) {
      intervalRef.current = setInterval(() => {
        setTimer(prev => prev + 1);
      }, 1000);
    } else {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
      }
    }

    return () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
      }
    };
  }, [isRunning]);

  // 聚焦输入框
  const focusInput = () => {
    inputRef.current?.focus();
  };

  // 选择输入框文本
  const selectInputText = () => {
    inputRef.current?.select();
  };

  // 滚动到指定元素
  const scrollToItem = (index: number) => {
    itemsRef.current[index]?.scrollIntoView({ behavior: 'smooth' });
  };

  // 添加新项目
  const addItem = () => {
    const newItem = `项目${items.length + 1}`;
    setItems(prev => [...prev, newItem]);
  };

  // 存储回调函数示例
  const handleCallback = () => {
    console.log('回调被调用，当前时间:', new Date().toLocaleTimeString());
  };

  useEffect(() => {
    callbackRef.current = handleCallback;
  });

  const triggerCallback = () => {
    callbackRef.current?.();
  };

  return (
    <div className="demo-page">
      <h1>useRef Hook 演示</h1>
      <p className="description">
        useRef返回一个可变的ref对象，其.current属性被初始化为传入的参数。
      </p>

      {/* 访问DOM元素 */}
      <section className="demo-section">
        <h2>1. 访问和操作DOM元素</h2>
        <div className="dom-access-demo">
          <input
            ref={inputRef}
            type="text"
            value={inputValue}
            onChange={(e) => setInputValue(e.target.value)}
            placeholder="输入一些文字..."
          />
          <div className="button-group">
            <button onClick={focusInput}>聚焦输入框</button>
            <button onClick={selectInputText}>选择文本</button>
            <button onClick={() => setInputValue('')}>清空</button>
          </div>
          <p>输入框值: {inputValue}</p>
        </div>
      </section>

      {/* 存储可变值 */}
      <section className="demo-section">
        <h2>2. 存储可变值（不触发重新渲染）</h2>
        <div className="mutable-value-demo">
          <p>计数器值: {count}</p>
          <p>渲染次数: {renderCount.current}（使用useRef存储）</p>
          <p>前一个值: {prevCountRef.current ?? '无'}（使用useRef存储）</p>
          <div className="button-group">
            <button onClick={() => setCount(count + 1)}>增加</button>
            <button onClick={() => setCount(count - 1)}>减少</button>
            <button onClick={() => setCount(0)}>重置</button>
          </div>
          <p className="note">
            注意：renderCount.current的变化不会触发组件重新渲染
          </p>
        </div>
      </section>

      {/* 存储定时器ID */}
      <section className="demo-section">
        <h2>3. 存储定时器ID</h2>
        <div className="timer-demo">
          <h3>计时器: {timer}秒</h3>
          <div className="button-group">
            <button onClick={() => setIsRunning(!isRunning)}>
              {isRunning ? '暂停' : '开始'}
            </button>
            <button onClick={() => {
              setTimer(0);
              setIsRunning(false);
            }}>重置</button>
          </div>
          <p className="note">
            定时器ID存储在useRef中，组件重新渲染时不会改变
          </p>
        </div>
      </section>

      {/* 存储DOM元素集合 */}
      <section className="demo-section">
        <h2>4. 存储DOM元素集合</h2>
        <div className="dom-collection-demo">
          <div className="controls">
            <button onClick={addItem}>添加项目</button>
          </div>
          
          <div className="items-container">
            {items.map((item, index) => (
              <div
                key={index}
                ref={el => itemsRef.current[index] = el}
                className="item"
                onClick={() => scrollToItem(index)}
              >
                {item}
              </div>
            ))}
          </div>
          
          <div className="scroll-controls">
            {items.map((_, index) => (
              <button key={index} onClick={() => scrollToItem(index)}>
                滚动到 {index + 1}
              </button>
            ))}
          </div>
        </div>
      </section>

      {/* 存储回调函数 */}
      <section className="demo-section">
        <h2>5. 存储回调函数</h2>
        <div className="callback-demo">
          <button onClick={triggerCallback}>触发回调</button>
          <p className="note">
            回调函数存储在useRef中，可以在事件处理程序中访问
          </p>
        </div>
      </section>

      {/* 使用要点 */}
      <section className="demo-section">
        <h2>6. 使用要点与最佳实践</h2>
        <div className="best-practices">
          <div className="practice-item">
            <h3>常见用途</h3>
            <ul>
              <li>访问DOM元素</li>
              <li>存储定时器ID</li>
              <li>存储可变值（不触发重新渲染）</li>
              <li>存储前一个值</li>
              <li>存储回调函数</li>
            </ul>
          </div>

          <div className="practice-item">
            <h3>注意事项</h3>
            <ul>
              <li>ref.current的变化不会触发重新渲染</li>
              <li>不要在渲染过程中读取或写入ref.current</li>
              <li>使用ref存储DOM元素时，确保元素已挂载</li>
            </ul>
          </div>

          <div className="practice-item">
            <h3>vs useState</h3>
            <ul>
              <li>useState：状态变化会触发重新渲染</li>
              <li>useRef：值变化不会触发重新渲染</li>
              <li>useState：用于需要在UI中显示的状态</li>
              <li>useRef：用于不需要触发重新渲染的值</li>
            </ul>
          </div>
        </div>
      </section>

      {/* 代码示例 */}
      <section className="demo-section">
        <h2>7. 代码示例</h2>
        <div className="code-example">
          <h3>基本语法:</h3>
          <pre>
{`// 创建ref
const myRef = useRef(initialValue);

// 访问DOM元素
const inputRef = useRef<HTMLInputElement>(null);

// 使用
inputRef.current?.focus();

// 存储可变值
const countRef = useRef(0);
countRef.current += 1;`}
          </pre>

          <h3>获取前一个值:</h3>
          <pre>
{`const [count, setCount] = useState(0);
const prevCountRef = useRef<number>();

useEffect(() => {
  prevCountRef.current = count;
});

console.log('前一个值:', prevCountRef.current);
console.log('当前值:', count);`}
          </pre>
        </div>
      </section>
    </div>
  );
};

export default UseRefDemo;